Ball b;
FrictionArea fa;
FrictionButton[] frictionButtons = new FrictionButton[4];

void setup(){
  // Set canvas size
  size(800, 800);
  
  // Create ball and friction area objects
  b = new Ball();
  fa = new FrictionArea(200, color(180));
  
  // Create buttons that can change the surface of the friction area
  frictionButtons[0] = new FrictionButton(new PVector(300, 50), "No Friction", color(180));
  frictionButtons[1] = new FrictionButton(new PVector(425, 50), "Grass", color(144, 194, 128));
  frictionButtons[2] = new FrictionButton(new PVector(550, 50), "Sand", color(194, 178, 128));
  frictionButtons[3] = new FrictionButton(new PVector(675, 50), "Water", color(128, 144, 194));
}

void draw(){
  background(0);
  // Print the current velocity
  displayVelocityInfo();
  
  // Ball methods
  b.display();
  b.move();
  b.edgeStop();
  b.displayStartButton();
  
  // Friction area methods
  fa.display();
  
  // Button methods
  for (int i = 0; i < frictionButtons.length; i++){
    frictionButtons[i].display();
    frictionButtons[i].changeCursor();
  }
  changeFAState();
  
  // Apply friction to the ball, when it is in the friction area
  applyFrictionFromFA();
  
  // Print the word "Surface" above the friction buttons
  textSize(22);
  fill(255);
  textAlign(CENTER, CENTER);
  text("Surface", 530, 20);
}

// Apply friction by checking what kind of surface the ball is rolling over
void applyFrictionFromFA(){
  if (fa.state == "No Friction"){
    b.applyForce(b.applyFriction(0));
  } else if (fa.state == "Grass" && (b.location.x >= fa.startCoordinate.x
               && b.location.x <= fa.startCoordinate.x + fa.areaLength)){
    b.applyForce(b.applyFriction(0.025));          
  }
  else if (fa.state == "Sand" && (b.location.x >= fa.startCoordinate.x
            && b.location.x <= fa.startCoordinate.x + fa.areaLength)){
    b.applyForce(b.applyFriction(0.05));          
  }
  else if (fa.state == "Water" && (b.location.x >= fa.startCoordinate.x
             && b.location.x <= fa.startCoordinate.x + fa.areaLength)){
    b.applyForce(b.applyFriction(0.1));          
  } else{
    b.applyForce(b.applyFriction(0));
  }
}

// Print current velocity
void displayVelocityInfo(){
  textSize(16);
  textAlign(LEFT);
  fill(255);
  text("Velocity: " + nf(b.velocity.x, 0, 2), 10, 25);
}

// Change the friction area surface type, depending on which button you press
void changeFAState(){
  for (FrictionButton fb: frictionButtons){
    if (mouseX < fb.location.x + fb.buttonLength && mouseX > fb.location.x &&
      mouseY < fb.location.y + fb.buttonHeight && mouseY > fb.location.y && mousePressed){
        fa.state = fb.label;
        fa.col = fb.col;
    }
  }
}
